/**
 * 
 */
package edu.hadassah.store.management;

import edu.hadassah.store.client.IClient;
import edu.hadassah.store.employee.IEmployee;
import edu.hadassah.store.order.IOrder;
import edu.hadassah.store.order.IOrderFactory;
import edu.hadassah.store.order.IOrderInfo;
import edu.hadassah.store.repository.IRepository;
import edu.hadassah.store.uniqueid.IUniqueId;

/**
 * @author persikov
 *
 */
public class StoreManagement implements IStoreManagement {

	private IRepository<IUniqueId, Client> clientRepository;
	private IRepository<IUniqueId, IEmployee> empoyeeRepository;
	private IRepository<IUniqueId, Order> orderRepository;
	private IOrderFactory orderFactory ;
	
	/**
	 * @param client
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#addClient(edu.hadassah.store.client.IClient)
	 */
	public void addClient(IClient client) {
		Client clientImpl = new Client(client);
		clientRepository.add(client.getId(), clientImpl);
	}

	/**
	 * @param employee
	 * @return
	 */
	public void addEmployee(IEmployee employee) {
		empoyeeRepository.add(employee.getId(), employee);
	}
	/**
	 * @param clientId
	 * @param orderInfo
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#addOrder(java.lang.String, edu.hadassah.store.order.IOrder)
	 */
	public IUniqueId addOrder(IOrderInfo orderInfo) {
		Order newOrder = (Order)orderFactory.createOrder(orderInfo);
		
		Client client = clientRepository.get(newOrder.getClientId());
		if (client == null){
			return null;
		}
		orderRepository.add(newOrder.getId(), newOrder);
		client.addOrder(newOrder.getId());
		addOrderListeners(newOrder);
		return newOrder.getId();
	}

	/**
	 * @param order
	 */
	private void addOrderListeners(IOrder order) {
		for (IEmployee employee : empoyeeRepository) {
			NotificationManager.getInstance().addOrderListener(order.getId(), employee);
		}
	}

	/**
	 * @param order
	 */
	private void removeOrderListeners(IOrder order) {
		for (IEmployee employee : empoyeeRepository) {
			NotificationManager.getInstance().removeOrderListener(order.getId(), employee);
		}
	}
	/**
	 * @param clientId
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#getClient(java.lang.String)
	 */
	public IClient getClient(IUniqueId clientId) {
		return clientRepository.get(clientId);
	}

	/**
	 * @param client
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#removeClient(edu.hadassah.store.client.IClient)
	 */
	public boolean removeClient(IUniqueId clientId) {
		IClient client = clientRepository.get(clientId);
		if (client == null || client.hasOrders()){
			return false;
		}
		return clientRepository.remove(clientId);
	}

	/**
	 * @param clientId
	 * @param order
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#removeOrder(java.lang.String, edu.hadassah.store.order.IOrder)
	 */
	public boolean removeOrder(IUniqueId orderId) {
		
		IOrder order = orderRepository.get(orderId);
		boolean removed = orderRepository.remove(orderId);
		if (removed){
			Client client = clientRepository.get(order.getClientId());
			client.removeOrder(order.getId());
			removeOrderListeners(order);
		}
		return removed;
	}

	/**
	 * @param clientRepository the clientRepository to set
	 */
	public void setClientRepository(IRepository<IUniqueId, Client> clientRepository) {
		this.clientRepository = clientRepository;
	}
	/**
	 * @param orderRepository
	 */
	public void setOrderRepository(IRepository<IUniqueId, Order> orderRepository) {
		this.orderRepository = orderRepository;
	}

	/**
	 * @param empoyeeRepository the empoyeeRepository to set
	 */
	public void setEmpoyeeRepository(
			IRepository<IUniqueId, IEmployee> empoyeeRepository) {
		this.empoyeeRepository = empoyeeRepository;
	}

	/**
	 * @param employeeId
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#getEmployee(edu.hadassah.store.uniqueid.IUniqueId)
	 */
	public IEmployee getEmployee(IUniqueId employeeId) {
		return empoyeeRepository.get(employeeId);
	}

	/**
	 * @param employee
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#removeEmployee(edu.hadassah.store.employee.IEmployee)
	 */
	public boolean removeEmployee(IEmployee employee) {
		boolean removed = empoyeeRepository.remove(employee.getId());
		if (removed) {
			for (IOrder order : orderRepository) {
				NotificationManager.getInstance().removeOrderListener(order.getId(), employee);
			}
		}
		return removed;
	}

	/**
	 * @param orderId
	 * @param updatedOrder
	 * @return
	 * @see edu.hadassah.store.management.IStoreManagement#updateOrder(edu.hadassah.store.uniqueid.IUniqueId, edu.hadassah.store.order.IOrder)
	 */
	public boolean updateOrder(IUniqueId orderId, IOrderInfo updateOrder) {
		Order order = orderRepository.get(orderId);
		if (order == null){
			return false;
		}
		IOrderInfo oldOrderMemento = order.toMemento();
		order.updateOrderInfo(updateOrder);
		NotificationManager.getInstance().fireOrderChange(order.getId(), oldOrderMemento, updateOrder);
		return true;
		
	}

	/**
	 * @param orderFactory the orderFactory to set
	 */
	public void setOrderFactory(IOrderFactory orderFactory) {
		this.orderFactory = orderFactory;
	}


}
